{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# part-1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [group_by](https://www.30secondsofcode.org/python/s/group-by)\n",
    "Python, List, Dictionary, Intermediate\n",
    "\n",
    "Groups the elements of a list based on the given function.\n",
    "\n",
    "Use `map()` and `fn` to map the values of the list to the keys of a dictionary. Use list comprehension to map each element to the appropriate `key`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:00:50.645748Z",
     "start_time": "2020-08-26T14:00:50.640968Z"
    }
   },
   "outputs": [],
   "source": [
    "def group_by(lst, fn):\n",
    "    return {key : [el for el in lst if fn(el) == key] for key in map(fn, lst)}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:08:32.283721Z",
     "start_time": "2020-08-26T14:08:32.274480Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{6: [6.1, 6.3], 4: [4.2]}\n",
      "{7: [6.4], 3: [2.5], 8: [7.2]}\n",
      "{3: ['one', 'two'], 5: ['three']}\n",
      "{True: [4], False: [-1, 0]}\n"
     ]
    }
   ],
   "source": [
    "from math import floor,ceil\n",
    "\n",
    "print(group_by([6.1, 4.2, 6.3], floor))\n",
    "print(group_by([6.4, 2.5, 7.2], ceil))\n",
    "print(group_by(['one', 'two', 'three'], len))\n",
    "\n",
    "f = lambda x: x>0\n",
    "print(group_by([4, -1, 0], f))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:03:29.337469Z",
     "start_time": "2020-08-26T14:03:29.328907Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__doc__',\n",
       " '__file__',\n",
       " '__loader__',\n",
       " '__name__',\n",
       " '__package__',\n",
       " '__spec__',\n",
       " 'acos',\n",
       " 'acosh',\n",
       " 'asin',\n",
       " 'asinh',\n",
       " 'atan',\n",
       " 'atan2',\n",
       " 'atanh',\n",
       " 'ceil',\n",
       " 'comb',\n",
       " 'copysign',\n",
       " 'cos',\n",
       " 'cosh',\n",
       " 'degrees',\n",
       " 'dist',\n",
       " 'e',\n",
       " 'erf',\n",
       " 'erfc',\n",
       " 'exp',\n",
       " 'expm1',\n",
       " 'fabs',\n",
       " 'factorial',\n",
       " 'floor',\n",
       " 'fmod',\n",
       " 'frexp',\n",
       " 'fsum',\n",
       " 'gamma',\n",
       " 'gcd',\n",
       " 'hypot',\n",
       " 'inf',\n",
       " 'isclose',\n",
       " 'isfinite',\n",
       " 'isinf',\n",
       " 'isnan',\n",
       " 'isqrt',\n",
       " 'ldexp',\n",
       " 'lgamma',\n",
       " 'log',\n",
       " 'log10',\n",
       " 'log1p',\n",
       " 'log2',\n",
       " 'modf',\n",
       " 'nan',\n",
       " 'perm',\n",
       " 'pi',\n",
       " 'pow',\n",
       " 'prod',\n",
       " 'radians',\n",
       " 'remainder',\n",
       " 'sin',\n",
       " 'sinh',\n",
       " 'sqrt',\n",
       " 'tan',\n",
       " 'tanh',\n",
       " 'tau',\n",
       " 'trunc']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import math\n",
    "dir(math)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [filter_unique](https://www.30secondsofcode.org/python/s/filter-unique) & filter_non_unique\n",
    "Python, List, Beginner\n",
    "\n",
    "Filters out the unique values in a list.\n",
    "\n",
    "Use a `collections.Counter` to get the count of each value in the list. Use list comprehension to create a list containing only the non-unique values.\n",
    "\n",
    "`collections.Counter`：Counter中文意思是计数器，也就是我们常用于统计的一种数据类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:39:21.694745Z",
     "start_time": "2020-08-26T14:39:21.689473Z"
    }
   },
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "\n",
    "def filter_unique(lst):\n",
    "    return [item for item, count in Counter(lst).items() if count > 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:39:37.666003Z",
     "start_time": "2020-08-26T14:39:37.657772Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 4]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filter_unique([1, 2, 2, 3, 4, 4, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:41:07.204456Z",
     "start_time": "2020-08-26T14:41:07.199531Z"
    }
   },
   "outputs": [],
   "source": [
    "def filter_non_unique(lst):\n",
    "    return [item for item, count in Counter(lst).items() if count == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:41:24.867633Z",
     "start_time": "2020-08-26T14:41:24.859409Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 3, 5]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "filter_non_unique([1, 2, 2, 3, 4, 4, 5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [bifurcate](https://www.30secondsofcode.org/python/s/bifurcate)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Splits values into two groups. If an element in `filter` is `True`, the corresponding element in the collection belongs to the first group; otherwise, it belongs to the second group.\n",
    "\n",
    "Use list comprehension and `enumerate()` to add elements to groups, based on `filter`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:43:20.097152Z",
     "start_time": "2020-08-26T14:43:20.091866Z"
    }
   },
   "outputs": [],
   "source": [
    "def bifurcate(lst, filter):\n",
    "    return [\n",
    "        [x for i, x in enumerate(lst) if filter[i] == True],\n",
    "        [x for i, x in enumerate(lst) if filter[i] == False]\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:43:30.263464Z",
     "start_time": "2020-08-26T14:43:30.254905Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[['beep', 'boop', 'bar'], ['foo']]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bifurcate(['beep', 'boop', 'foo', 'bar'], [True, True, False, True])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [union_by](https://www.30secondsofcode.org/python/s/union-by)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns every element that exists in any of the two lists once, after applying the provided function to each element of both.\n",
    "\n",
    "Create a `set` by applying `fn` to each element in `a`, then use list comprehension in combination with `fn` on `b` to only keep values not contained in the previously created set, `_a`. Finally, create a `set` from the previous result and `a` and transform it into a `list`\n",
    "\n",
    "取集合a，以及取集合b中的floor(b[n])不在集合a中的floor(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T14:47:48.211527Z",
     "start_time": "2020-08-26T14:47:48.206097Z"
    }
   },
   "outputs": [],
   "source": [
    "def union_by(a, b, fn):\n",
    "    _a = set(map(fn, a))\n",
    "    print(_a)\n",
    "    return list(set(a + [item for item in b if fn(item) not in _a]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T15:55:47.909367Z",
     "start_time": "2020-08-26T15:55:47.899015Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{2, 3}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[2.1, 3.5, 4.2]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import floor\n",
    "union_by([2.1, 3.5], [4.2, 3.3], floor)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [Code Anatomy - Writing high performance Python code](https://www.30secondsofcode.org/blog/s/code-anatomy-performant-python)\n",
    "\n",
    "`fiter(function. Iterable)`\n",
    "\n",
    "function: 用来筛选的函数. 在ﬁlter中会自动的把iterable中的元素传递给function. 然后根据function返回的True或者False来判断是否保留此项数据\n",
    "\n",
    "Iterable: 可迭代对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:05:20.517271Z",
     "start_time": "2020-08-26T16:05:20.512793Z"
    }
   },
   "outputs": [],
   "source": [
    "def difference(a, b):\n",
    "    return [item for item in a if item not in b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:05:41.397094Z",
     "start_time": "2020-08-26T16:05:41.391792Z"
    }
   },
   "outputs": [],
   "source": [
    "def difference(a, b):\n",
    "    _b = set(b)\n",
    "    return [item for item in a if item not in _b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:14:15.105744Z",
     "start_time": "2020-08-26T16:14:15.099595Z"
    }
   },
   "outputs": [],
   "source": [
    "def difference(a, b):\n",
    "    _b = set(b)\n",
    "    print(_b)\n",
    "    return list(filter(lambda item: item not in _b, a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:14:17.419256Z",
     "start_time": "2020-08-26T16:14:17.412279Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 4}\n",
      "[3]\n"
     ]
    }
   ],
   "source": [
    "print(difference([1, 2, 3], [1, 2, 2, 4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [intersection_by](https://www.30secondsofcode.org/python/s/intersection-by)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns a list of elements that exist in both lists, after applying the provided function to each list element of both.\n",
    "\n",
    "Create a `set` by applying `fn` to each element in `b`, then use list comprehension in combination with `fn` on `a` to only keep values contained in both lists.\n",
    "\n",
    "a : floor(a) if in floor(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:18:48.158403Z",
     "start_time": "2020-08-26T16:18:48.153003Z"
    }
   },
   "outputs": [],
   "source": [
    "def intersection_by(a, b, fn):\n",
    "    _b = set(map(fn, b))\n",
    "    return [item for item in a if fn(item) in _b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:18:57.800054Z",
     "start_time": "2020-08-26T16:18:57.791758Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2.1]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import floor\n",
    "intersection_by([2.1, 1.2], [2.3, 3.4],floor)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [symmetric_difference](https://www.30secondsofcode.org/python/s/symmetric-difference)\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the symmetric difference between two iterables, without filtering out duplicate values.\n",
    "\n",
    "Create a `set` from each list, then use list comprehension on each one to only keep values not contained in the previously created set of the other."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:42:06.302726Z",
     "start_time": "2020-08-27T10:42:06.296491Z"
    }
   },
   "outputs": [],
   "source": [
    "def symmetric_difference(a, b):\n",
    "    _a, _b = set(a), set(b)\n",
    "    return [item for item in a if item not in _b] + [item for item in b if item not in _a]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:42:15.038864Z",
     "start_time": "2020-08-27T10:42:15.032457Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 4]"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "symmetric_difference([1, 2, 3], [1, 2, 4])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [symmetric_difference_by](https://www.30secondsofcode.org/python/s/symmetric-difference-by)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns the symmetric difference between two lists, after applying the provided function to each list element of both.\n",
    "\n",
    "Create a `set` by applying `fn` to each element in every list, then use list comprehension in combination with `fn` on each one to only keep values not contained in the previously created set of the other.\n",
    "\n",
    "集合 floor(a) 中不在集合 floor(b) 中 & 相反的列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:27:22.409104Z",
     "start_time": "2020-08-26T16:27:22.402280Z"
    }
   },
   "outputs": [],
   "source": [
    "def symmetric_difference_by(a, b, fn):\n",
    "    _a, _b = set(map(fn, a)), set(map(fn, b))\n",
    "    print(_a, _b)\n",
    "    return [item for item in a if fn(item) not in _b] + [item for item in b if fn(item) not in _a]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:27:46.830562Z",
     "start_time": "2020-08-26T16:27:46.821394Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2} {2, 3}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[1.2, 3.4]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import floor\n",
    "symmetric_difference_by([2.1, 1.2], [2.3, 3.4],floor)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [difference_by](https://www.30secondsofcode.org/python/s/difference-by)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns the difference between two lists, after applying the provided function to each list element of both.\n",
    "\n",
    "Create a `set` by applying `fn` to each element in `b`, then use list comprehension in combination with `fn` on `a` to only keep values not contained in the previously created set, `_b`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:47:59.798147Z",
     "start_time": "2020-08-27T10:47:59.793249Z"
    }
   },
   "outputs": [],
   "source": [
    "def difference_by(a, b, fn):\n",
    "    _b = set(map(fn, b))\n",
    "    return [item for item in a if fn(item) not in _b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:48:26.099251Z",
     "start_time": "2020-08-27T10:48:26.092329Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.2]\n",
      "[{'x': 2}]\n"
     ]
    }
   ],
   "source": [
    "from math import floor\n",
    "print(difference_by([2.1, 1.2], [2.3, 3.4], floor))\n",
    "print(difference_by([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], lambda v : v['x']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [merge](https://www.30secondsofcode.org/python/s/merge)\n",
    "Python, List, Math, Advanced\n",
    "\n",
    "Merges two or more lists into a list of lists, combining elements from each of the input lists based on their positions.\n",
    "\n",
    "Use `max` combined with list comprehension to get the length of the longest list in the arguments. Use `range()` in combination with the `max_length` variable to loop as many times as there are elements in the longest list. If a list is shorter than `max_length`, use `fill_value` for the remaining items (defaults to `None`).\n",
    "\n",
    "`zip()` and `itertools.zip_longest()` provide similar functionality to this snippet."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:43:48.307230Z",
     "start_time": "2020-08-26T16:43:48.299840Z"
    }
   },
   "outputs": [],
   "source": [
    "def merge(*args, fill_value=None):\n",
    "    max_length = max([len(lst) for lst in args])\n",
    "    result = []\n",
    "    for i in range(max_length):\n",
    "        result.append([\n",
    "            args[k][i] if i < len(args[k]) else fill_value for k in range(len(args))\n",
    "        ])\n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:44:24.249825Z",
     "start_time": "2020-08-26T16:44:24.242430Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['a', 1, True], ['b', 2, False]]\n",
      "[['a', 1, True], [None, 2, False]]\n",
      "[['a', 1, True], ['_', 2, False]]\n"
     ]
    }
   ],
   "source": [
    "print(merge(['a', 'b'], [1, 2], [True, False]))\n",
    "print(merge(['a'], [1, 2], [True, False]))\n",
    "print(merge(['a'], [1, 2], [True, False], fill_value = '_'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [bifurcate_by](https://www.30secondsofcode.org/python/s/bifurcate-by)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Splits values into two groups according to a function, which specifies which group an element in the input list belongs to. If the function returns `True`, the element belongs to the first group; otherwise, it belongs to the second group.\n",
    "\n",
    "Use list comprehension to add elements to groups, based on `fn`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:48:08.658057Z",
     "start_time": "2020-08-26T16:48:08.652630Z"
    }
   },
   "outputs": [],
   "source": [
    "def bifurcate_by(lst, fn):\n",
    "    return [\n",
    "        [x for x in lst if fn(x)],\n",
    "        [x for x in lst if not fn(x)]\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:48:40.620942Z",
     "start_time": "2020-08-26T16:48:40.612852Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[['beep', 'boop', 'bar'], ['foo']]"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bifurcate_by(\n",
    "    ['beep', 'boop', 'foo', 'bar'], \n",
    "    lambda x: x[0] == 'b'\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [none](https://www.30secondsofcode.org/python/s/none)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns `False` if the provided function returns `True` for at least one element in the list, `True` otherwise.\n",
    "\n",
    "Use `all()` and `fn` to check if `fn` returns `False` for all the elements in the list.\n",
    "\n",
    "全部与条件相反"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:27:34.327164Z",
     "start_time": "2020-08-27T11:27:34.322126Z"
    }
   },
   "outputs": [],
   "source": [
    "def none(lst, fn=lambda x: x != 0):\n",
    "    return all(not fn(x) for x in lst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:29:01.919861Z",
     "start_time": "2020-08-27T11:29:01.912395Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(none([0, 1, 1, 0], lambda x: x >= 2 ))\n",
    "print(none([0, 1, 1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [every](https://www.30secondsofcode.org/python/s/every)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns `True` if the provided function returns `True` for every element in the list, `False` otherwise.\n",
    "\n",
    "Use `all()` in combination with `map` and `fn` to check if `fn` returns `True` for all elements in the list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:52:44.943924Z",
     "start_time": "2020-08-26T16:52:44.938946Z"
    }
   },
   "outputs": [],
   "source": [
    "def every(lst, fn=lambda x: x != 0):\n",
    "    return all(map(fn, lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-26T16:53:17.319771Z",
     "start_time": "2020-08-26T16:53:17.313149Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(every([4, 2, 3], lambda x: x > 1))\n",
    "print(every([0, 1, 2, 3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [some](https://www.30secondsofcode.org/python/s/some)\n",
    "Python, List, Function, Intermediate\n",
    "\n",
    "Returns `True` if the provided function returns `True` for at least one element in the list, `False` otherwise.\n",
    "\n",
    "Use`any()` in combination with `map()` and `fn` to check if `fn` returns `True` for any element in the list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:11:04.187732Z",
     "start_time": "2020-08-27T10:11:04.183559Z"
    }
   },
   "outputs": [],
   "source": [
    "def some(lst, fn=lambda x: x != 0):\n",
    "    return any(map(fn, lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:11:25.349811Z",
     "start_time": "2020-08-27T10:11:25.343288Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(some([0, 1, 2, 0], lambda x: x >= 2 ))\n",
    "print(some([0, 0, 0, 0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [longest_item](https://www.30secondsofcode.org/python/s/longest-item)\n",
    "Python, List, String, Intermediate\n",
    "\n",
    "Takes any number of iterable objects or objects with a length property and returns the longest one. If multiple objects have the same length, the first one will be returned.\n",
    "\n",
    "Use `max()` with `len` as the `key` to return the item with the greatest length.\n",
    "\n",
    "```py\n",
    "max(iterable, *[, key, default]) \n",
    "max(arg1, arg2, *args[, key]) \n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:03:27.110314Z",
     "start_time": "2020-08-27T10:03:27.104847Z"
    }
   },
   "outputs": [],
   "source": [
    "def longest_item(*args):\n",
    "    return max(args, key=len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:07:08.179634Z",
     "start_time": "2020-08-27T10:07:08.172277Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "testcase\n",
      "[1, 2, 3, 4, 5]\n",
      "[1, 2, 3]\n",
      "foot\n"
     ]
    }
   ],
   "source": [
    "print(longest_item('this', 'is', 'a', 'testcase'))\n",
    "print(longest_item([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]))\n",
    "print(longest_item([1, 2, 3], 'foo'))\n",
    "print(longest_item([1, 2, 3], 'foot'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [map_dictionary](https://www.30secondsofcode.org/python/s/map-dictionary)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Maps the values of a list to a dictionary using a function, where the key-value pairs consist of the original value as the key and the result of the function as the value.\n",
    "\n",
    "Use a `for` loop to iterate over the list's values, assigning the values produced by `fn` to each key of the dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:13:22.657357Z",
     "start_time": "2020-08-27T10:13:22.652260Z"
    }
   },
   "outputs": [],
   "source": [
    "def map_dictionary(itr, fn):\n",
    "    ret = {}\n",
    "    for x in itr:\n",
    "        ret[x] = fn(x)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:13:31.580197Z",
     "start_time": "2020-08-27T10:13:31.571953Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1: 1, 2: 4, 3: 9}"
      ]
     },
     "execution_count": 92,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "map_dictionary([1,2,3], lambda x: x * x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:19:33.377217Z",
     "start_time": "2020-08-27T10:19:33.370797Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 4, 9]\n"
     ]
    }
   ],
   "source": [
    "# test\n",
    "data = [1,2,3]\n",
    "data_ = [i*i for i in data]\n",
    "print(data_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [find_parity_outliers](https://www.30secondsofcode.org/python/s/find-parity-outliers)\n",
    "Python, List, Math, Intermediate\n",
    "\n",
    "Given a list, returns the items that are parity outliers.\n",
    "\n",
    "Use `collections.Counter` with a list comprehension to count even and odd values in the list, use `collections.Counter.most_common()` to get the most common parity. Use a list comprehension to find all elements that do not match the most common parity.\n",
    "\n",
    "偶数比奇数多则返回奇数列表，反之同理。\n",
    "相等则返回偶数列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:35:22.558839Z",
     "start_time": "2020-08-27T10:35:22.553361Z"
    }
   },
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "\n",
    "def find_parity_outliers(nums):\n",
    "    return [\n",
    "        x for x in nums\n",
    "        if x % 2 != Counter([n % 2 for n in nums]).most_common()[0][0]\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:35:53.536808Z",
     "start_time": "2020-08-27T10:35:53.530407Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3]\n",
      "[2, 4, 6]\n"
     ]
    }
   ],
   "source": [
    "print(find_parity_outliers([1, 2, 3, 4, 6]))\n",
    "print(find_parity_outliers([1, 2, 3, 4, 5, 6]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### most_common()[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T10:32:08.090524Z",
     "start_time": "2020-08-27T10:32:08.082225Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('eyes', 8), ('the', 5), ('look', 4)]\n",
      "eyes\n"
     ]
    }
   ],
   "source": [
    "# test\n",
    "words = [\n",
    "    'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',\n",
    "    'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',\n",
    "    'eyes', \"don't\", 'look', 'around', 'the', 'eyes', 'look', 'into',\n",
    "    'my', 'eyes', \"you're\", 'understand'\n",
    "]\n",
    "from collections import Counter\n",
    "word_counts = Counter(words)\n",
    "# 出现频率最高的3个单词\n",
    "top_three = word_counts.most_common(3)\n",
    "top_word = word_counts.most_common()[0][0]\n",
    "print(top_three)\n",
    "print(top_word)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [frequencies](https://www.30secondsofcode.org/python/s/frequencies)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns a dictionary with the unique values of a list as keys and their frequencies as the values.\n",
    "\n",
    "Use a `for` loop to populate a dictionary, `f`, with the unique values in `lst` as keys, adding to existing keys every time the same value is encountered."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:17:36.717823Z",
     "start_time": "2020-08-27T11:17:36.712794Z"
    }
   },
   "outputs": [],
   "source": [
    "from functools import reduce\n",
    "\n",
    "def frequencies(lst):\n",
    "    f = {}\n",
    "    for x in lst:\n",
    "        f[x] = f[x] + 1 if x in f else 1\n",
    "    return f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:17:45.836815Z",
     "start_time": "2020-08-27T11:17:45.829223Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 4, 'b': 2, 'c': 1}"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "frequencies(['a', 'b', 'a', 'c', 'a', 'a', 'b'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [initialize_list_with_values](https://www.30secondsofcode.org/python/s/initialize-list-with-values)\n",
    "Python, List, Beginner\n",
    "\n",
    "Initializes and fills a list with the specified value.\n",
    "\n",
    "Use list comprehension and `range()` to generate a list of length equal to `n`, filled with the desired values. Omit `val` to use the default value of `0`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:23:19.305337Z",
     "start_time": "2020-08-27T11:23:19.300513Z"
    }
   },
   "outputs": [],
   "source": [
    "def initialize_list_with_values(n, val = 0):\n",
    "    return [val for x in range(n)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:23:27.739701Z",
     "start_time": "2020-08-27T11:23:27.732299Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2, 2, 2, 2, 2]"
      ]
     },
     "execution_count": 127,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "initialize_list_with_values(5, 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [initialize_2d_list](https://www.30secondsofcode.org/python/s/initialize-2-d-list)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Initializes a 2D list of given width and height and value.\n",
    "\n",
    "Use list comprehension and `range()` to generate `h` rows where each is a list with length `h`, initialized with `val`. If `val` is not provided, default to `None`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:20:31.877447Z",
     "start_time": "2020-08-27T11:20:31.872231Z"
    }
   },
   "outputs": [],
   "source": [
    "def initialize_2d_list(w,h, val = None):\n",
    "    return [[val for x in range(w)] for y in range(h)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:22:12.274425Z",
     "start_time": "2020-08-27T11:22:12.263258Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0, 0], [0, 0]]\n",
      "[[None, None, None], [None, None, None], [None, None, None]]\n"
     ]
    }
   ],
   "source": [
    "print(initialize_2d_list(2, 2, 0))\n",
    "print(initialize_2d_list(3, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [sample](https://www.30secondsofcode.org/python/s/sample)\n",
    "Python, List, Random, Beginner\n",
    "\n",
    "Returns a random element from a list.\n",
    "\n",
    "Use `random.randint()` to generate a random number that corresponds to an index in the list, return the element at that index.\n",
    "\n",
    "`random.sample()` provides similar functionality to this snippet.\n",
    "\n",
    "在列表中随机取一个"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:31:09.103672Z",
     "start_time": "2020-08-27T11:31:09.098718Z"
    }
   },
   "outputs": [],
   "source": [
    "from random import randint\n",
    "\n",
    "def sample(lst):\n",
    "    return lst[randint(0, len(lst) - 1)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:31:29.470685Z",
     "start_time": "2020-08-27T11:31:29.461892Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sample([3, 7, 9, 11])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 170,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:41:09.910115Z",
     "start_time": "2020-08-27T11:41:09.905076Z"
    }
   },
   "outputs": [],
   "source": [
    "# random dict a key or value\n",
    "\n",
    "from random import choice\n",
    "\n",
    "proxies={'117.90.252.55:9000': 0, \n",
    "         '119.29.103.13:8888': 1, \n",
    "         '175.155.227.130:8118': 2, \n",
    "         '123.171.55.45:808': 3, \n",
    "         '117.69.230.18:27853': 4, \n",
    "         '125.83.193.152:8998': 5, \n",
    "         '222.208.83.175:9000': 6, \n",
    "         '223.145.230.146:6666': 7, \n",
    "         '117.68.241.52:808': 8, \n",
    "         '114.239.127.225:61234': 9}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:41:11.904828Z",
     "start_time": "2020-08-27T11:41:11.898655Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "114.239.127.225:61234\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "proxy = choice(list(proxies))\n",
    "proxy_value = proxies[choice(list(proxies))]\n",
    "print(proxy)\n",
    "print(proxy_value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [chunk](https://www.30secondsofcode.org/python/s/chunk)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Chunks a list into smaller lists of a specified size.\n",
    "\n",
    "Use `list()` and `range()` to create a list of the desired `size`. Use `map()` on the list and fill it with splices of the given list. Finally, return the created list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:48:44.705535Z",
     "start_time": "2020-08-27T11:48:44.699988Z"
    }
   },
   "outputs": [],
   "source": [
    "from math import ceil\n",
    "\n",
    "def chunk(lst, size):\n",
    "    return list(\n",
    "        map(lambda x: lst[x * size:x * size + size],\n",
    "        list(range(0, ceil(len(lst) / size))))\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-27T11:48:46.458769Z",
     "start_time": "2020-08-27T11:48:46.452753Z"
    }
   },
   "outputs": [],
   "source": [
    "chunk([1, 2, 3, 4, 5], 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [count_by](https://www.30secondsofcode.org/python/s/count-by)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Groups the elements of a list based on the given function and returns the count of elements in each group.\n",
    "\n",
    "Use `map()` to map the values of the given list using the given function. Iterate over the map and increase the element count each time it occurs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:09:56.364466Z",
     "start_time": "2020-08-28T09:09:56.359374Z"
    }
   },
   "outputs": [],
   "source": [
    "def count_by(arr, fn=lambda x: x):\n",
    "    key = {}\n",
    "    for el in map(fn, arr):\n",
    "        key[el] = 1 if el not in key else key[el] + 1\n",
    "    return key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:10:17.533969Z",
     "start_time": "2020-08-28T09:10:17.526889Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{6: 2, 4: 1}\n",
      "{3: 2, 5: 1}\n"
     ]
    }
   ],
   "source": [
    "from math import floor\n",
    "\n",
    "print(count_by([6.1, 4.2, 6.3], floor))\n",
    "print(count_by(['one', 'two', 'three'], len))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [flatten](https://www.30secondsofcode.org/python/s/flatten)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Flattens a list of lists once.\n",
    "\n",
    "Use nested list comprehension to extract each value from sub-lists in order."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:06:37.810850Z",
     "start_time": "2020-08-28T09:06:37.807025Z"
    }
   },
   "outputs": [],
   "source": [
    "def flatten(lst):\n",
    "    return [y for x in lst for y in x]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:06:39.806717Z",
     "start_time": "2020-08-28T09:06:39.800480Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 8]\n"
     ]
    }
   ],
   "source": [
    "print(flatten([[1,2,3,4],[5,6,7,8]]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [deep_flatten](https://www.30secondsofcode.org/python/s/deep-flatten)\n",
    "Python, List, Recursion, Intermediate\n",
    "\n",
    "Deep flattens a list.\n",
    "\n",
    "Use recursion. Use `isinstance()` with `collections.abc.Iterable` to check if an element is iterable. If it is, apply `deep_flatten()` recursively, otherwise return `[lst]`.\n",
    "\n",
    "`isinstance()` 函数来判断一个对象是否是一个已知的类型，类似 `type()`。\n",
    "\n",
    "isinstance() 与 type() 区别：\n",
    "- type() 不会认为子类是一种父类类型，不考虑继承关系。\n",
    "- isinstance() 会认为子类是一种父类类型，考虑继承关系。\n",
    "\n",
    "如果要判断两个类型是否相同推荐使用 isinstance()。\n",
    "\n",
    "----\n",
    "集合数据类型如list、dict、str等是Iterable\n",
    "\n",
    "[python中的Iterable对象和Iterator](https://www.cnblogs.com/zf-blog/p/10613533.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:13:38.937653Z",
     "start_time": "2020-08-28T09:13:38.931457Z"
    }
   },
   "outputs": [],
   "source": [
    "from collections.abc import Iterable\n",
    "\n",
    "def deep_flatten(lst):\n",
    "    return [a for i in lst for a in deep_flatten(i)] if isinstance(lst, Iterable) else [lst]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:13:48.609571Z",
     "start_time": "2020-08-28T09:13:48.601487Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "print(deep_flatten([1, [2], [[3], 4], 5]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## similarity\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns a list of elements that exist in both lists.\n",
    "\n",
    "Use list comprehension on `a` to only keep values contained in both lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:21:38.207341Z",
     "start_time": "2020-08-28T09:21:38.202487Z"
    }
   },
   "outputs": [],
   "source": [
    "def similarity(a, b):\n",
    "    return [item for item in a if item in b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:21:47.716808Z",
     "start_time": "2020-08-28T09:21:47.710738Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2]\n"
     ]
    }
   ],
   "source": [
    "print(similarity([1, 2, 3], [1, 2, 4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## transpose\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns the transpose of a two-dimensional list.\n",
    "\n",
    "Use `*lst` to get the passed list as tuples. Use `zip()` in combination with `list()` to create the transpose of the given two-dimensional list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:24:46.399701Z",
     "start_time": "2020-08-28T09:24:46.394558Z"
    }
   },
   "outputs": [],
   "source": [
    "def transpose(lst):\n",
    "    return list(zip(*lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:25:00.298096Z",
     "start_time": "2020-08-28T09:25:00.291763Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)]\n"
     ]
    }
   ],
   "source": [
    "print(transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [most_frequent](https://www.30secondsofcode.org/python/s/most-frequent)\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the most frequent element in a list.\n",
    "\n",
    "Use `set(list)` to get the unique values in the `list` combined with `max()` to find the element that has the most appearances.\n",
    "\n",
    "`count()` 方法用于统计某个元素在列表中出现的次数。\n",
    "\n",
    "`key=list.count`：类似于lambda `max(range(10),key=lambda x: x > 3)   #4`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:28:52.979804Z",
     "start_time": "2020-08-28T09:28:52.975108Z"
    }
   },
   "outputs": [],
   "source": [
    "def most_frequent(list):\n",
    "    return max(set(list), key=list.count)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T09:28:59.761821Z",
     "start_time": "2020-08-28T09:28:59.749529Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "most_frequent([1, 2, 1, 2, 3, 2, 1, 4, 2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [shuffle](https://www.30secondsofcode.org/python/s/shuffle)\n",
    "Python, List, Random, Intermediate\n",
    "\n",
    "Randomizes the order of the values of an list, returning a new list.\n",
    "\n",
    "Uses the Fisher-Yates algorithm to reorder the elements of the list.\n",
    "\n",
    "`random.shuffle` provides similar functionality to this snippet.\n",
    "\n",
    "[公平的洗牌算法](https://github.com/anlzou/daily-algorithm/blob/master/problems/M0004_Knuth.md)\n",
    "\n",
    "### 补充：copy（）和deepcopy（）\n",
    "- 我们寻常意义的复制就是深复制，即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。 \n",
    "- 而浅复制并不会产生一个独立的对象单独存在，他只是将原有的数据块打上一个新标签，所以当其中一个标签被改变的时候，数据块就会发生变化，另一个标签也会随之改变。这就和我们寻常意义上的复制有所不同了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:04:34.722776Z",
     "start_time": "2020-08-28T12:04:34.716998Z"
    }
   },
   "outputs": [],
   "source": [
    "from copy import deepcopy\n",
    "from random import randint\n",
    "\n",
    "def shuffle(lst):\n",
    "    temp_lst = deepcopy(lst)\n",
    "    m = len(temp_lst)\n",
    "    while (m):\n",
    "        m -= 1\n",
    "        i = randint(0, m)\n",
    "        temp_lst[m], temp_lst[i] = temp_lst[i], temp_lst[m]\n",
    "    return temp_lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:07:40.008910Z",
     "start_time": "2020-08-28T12:07:40.002186Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 5, 6, 1, 4, 2]\n"
     ]
    }
   ],
   "source": [
    "foo = [1,2,3,4,5,6]\n",
    "print(shuffle(foo))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [to_dictionary](https://www.30secondsofcode.org/python/s/to-dictionary) & to_list & to_tuple\n",
    "Python, List, Dictionary, Intermediate\n",
    "\n",
    "Combines two lists into a dictionary, where the elements of the first one serve as the keys and the elements of the second one serve as the values. The values of the first list need to be unique and hashable.\n",
    "\n",
    "Use `zip()` in combination with a list comprehension to combine the values of the two lists, based on their positions.\n",
    "\n",
    "`zip()` 函数用于将可迭代的对象作为参数，将对象中对应的元素打包成一个个元组，然后返回由这些元组组成的对象，这样做的好处是节约了不少的内存。\n",
    "\n",
    "我们可以使用 list() 转换来输出列表。\n",
    "\n",
    "如果各个迭代器的元素个数不一致，则返回列表长度与最短的对象相同，利用 `*` 号操作符，可以将元组解压为列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:10:52.286664Z",
     "start_time": "2020-08-28T12:10:52.281911Z"
    }
   },
   "outputs": [],
   "source": [
    "def to_dictionary(keys, values):\n",
    "    return {key:value for key, value in zip(keys, values)}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:11:04.891163Z",
     "start_time": "2020-08-28T12:11:04.884265Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 1, 'b': 2}\n"
     ]
    }
   ],
   "source": [
    "print(to_dictionary(['a', 'b'], [1, 2]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:14:13.375987Z",
     "start_time": "2020-08-28T12:14:13.370926Z"
    }
   },
   "outputs": [],
   "source": [
    "# double list to list\n",
    "def to_list(keys, values):\n",
    "    return [[key,value] for key, value in zip(keys, values)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:15:57.365767Z",
     "start_time": "2020-08-28T12:15:57.359808Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['a', 1], ['b', 2], ['c', 3]]\n"
     ]
    }
   ],
   "source": [
    "print(to_list(['a', 'b', 'c'], [1, 2, 3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:17:07.552714Z",
     "start_time": "2020-08-28T12:17:07.547854Z"
    }
   },
   "outputs": [],
   "source": [
    "# double list to tuple\n",
    "def to_tuple(keys, values):\n",
    "    return [(key,value) for key, value in zip(keys, values)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T12:15:48.576272Z",
     "start_time": "2020-08-28T12:15:48.567160Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('a', 1), ('b', 2), ('c', 3)]\n"
     ]
    }
   ],
   "source": [
    "print(to_tuple(['a', 'b', 'c'], [1, 2, 3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### [What is the difference between lists and tuples in Python?](https://www.30secondsofcode.org/blog/s/python-lists-tuples)\n",
    "**Lists**\n",
    "- Syntax: [1, 2, 3]\n",
    "- Contained elements are mutable (can be changed after creation)\n",
    "- Lists have a variable length\n",
    "- A list takes up more memory than a tuple\n",
    "\n",
    "**翻译：**\n",
    "- 包含的元素是可变的（可以在创建后更改）\n",
    "- 列表的长度可变\n",
    "- 列表比元组占用更多的内存\n",
    "\n",
    "**Tuples**\n",
    "- Syntax: (1, 2, 3)\n",
    "- Contained elements are immutable (cannot be changed after creation)\n",
    "- Tuples have a fixed length\n",
    "- A tuple takes up less memory than a list\n",
    "\n",
    "**翻译：**\n",
    "- 包含的元素是不可变的（创建后不能更改）\n",
    "- 元组的长度是固定的\n",
    "- 元组比列表占用更少的内存\n",
    "\n",
    "**何时使用每一个？**\n",
    "\n",
    "列表提供了一个更易访问的API，当需要存储类似类型的对象并且在应用程序的执行过程中预期会发生变化时，应该使用列表。另一方面，元组应该用于不可变的数据，其行为更像常量而不是变量。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [cast_list](https://www.30secondsofcode.org/python/s/cast-list)\n",
    "Python, List, Beginner\n",
    "\n",
    "Casts the provided value as a list if it's not one.\n",
    "\n",
    "Use `isinstance()` to check if the given value is enumerable and return it by using `list()` or encapsulated in a list accordingly."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:24:45.587082Z",
     "start_time": "2020-08-28T15:24:45.581822Z"
    }
   },
   "outputs": [],
   "source": [
    "def cast_list(val):\n",
    "    return list(val) if isinstance(val, (tuple, list, set, dict)) else [val]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:25:14.315771Z",
     "start_time": "2020-08-28T15:25:14.309010Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['foo']\n",
      "[1]\n",
      "['foo', 'bar']\n"
     ]
    }
   ],
   "source": [
    "print(cast_list('foo'))\n",
    "print(cast_list([1]))\n",
    "print(cast_list(('foo', 'bar')))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [find_index](https://www.30secondsofcode.org/python/s/find-index)\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the index of the first element in the provided list that satisfies the provided testing function.\n",
    "\n",
    "Use list comprehension, `enumerate()` and `next()` to return the index of the first element in `lst` for which `fn` returns `True`.\n",
    "\n",
    "---\n",
    "`enumerate()` 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列，同时列出数据和数据下标，一般用在 for 循环当中。\n",
    "\n",
    "**语法**\n",
    "```py\n",
    "enumerate(sequence, [start=0])\n",
    "```\n",
    "**参数**\n",
    "- sequence -- 一个序列、迭代器或其他支持迭代对象。\n",
    "- start -- 下标起始位置。\n",
    "\n",
    "**返回值**\n",
    "\n",
    "返回 enumerate(枚举) 对象。\n",
    "\n",
    "---\n",
    "`next()` 返回迭代器的下一个项目。\n",
    "\n",
    "`next()` 函数要和生成迭代器的iter() 函数一起使用。\n",
    "\n",
    "**语法**\n",
    "```py\n",
    "next(iterable[, default])\n",
    "```\n",
    "\n",
    "**参数说明：**\n",
    "- iterable -- 可迭代对象\n",
    "- default -- 可选，用于设置在没有下一个元素时返回该默认值，如果不设置，又没有下一个元素则会触发 StopIteration 异常。\n",
    "\n",
    "**返回值**\n",
    "\n",
    "返回对象帮助信息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:50:47.120631Z",
     "start_time": "2020-08-28T15:50:47.115729Z"
    }
   },
   "outputs": [],
   "source": [
    "def find_index(lst, fn):\n",
    "    return next(i for i, x in enumerate(lst) if fn(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:50:58.713732Z",
     "start_time": "2020-08-28T15:50:58.707388Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "print(find_index([1, 2, 3, 4, 7, 5, 6], lambda n: 4 <= n <= 6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "返回 [ index, value ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:16:55.868173Z",
     "start_time": "2020-08-29T11:16:55.863342Z"
    }
   },
   "outputs": [],
   "source": [
    "def find_index(lst, fn):\n",
    "    return next([i,x] for i, x in enumerate(lst) if fn(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:16:59.952966Z",
     "start_time": "2020-08-29T11:16:59.945817Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 4]\n"
     ]
    }
   ],
   "source": [
    "print(find_index([1, 2, 3, 4, 7, 5, 6], lambda n: 4 <= n <= 6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [find_last_index](https://www.30secondsofcode.org/python/s/find-last-index)\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the index of the last element in the provided list that satisfies the provided testing function.\n",
    "\n",
    "Use list comprehension, `enumerate()` and `next()` to return the index of the last element in `lst` for which `fn` returns `True`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:51:00.743876Z",
     "start_time": "2020-08-28T15:51:00.738173Z"
    }
   },
   "outputs": [],
   "source": [
    "def find_last_index(lst, fn):\n",
    "    return len(lst)- 1 - next(i for i, x in enumerate(lst[::-1]) if fn(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-28T15:51:02.677752Z",
     "start_time": "2020-08-28T15:51:02.672738Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n"
     ]
    }
   ],
   "source": [
    "print(find_last_index([1, 2, 3, 4, 7, 5, 6], lambda n: 4 <= n <= 6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [find](https://www.30secondsofcode.org/python/s/find) & find_last\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the value of the first element in the provided list that satisfies the provided testing function.\n",
    "\n",
    "Use list comprehension and `next()` to return the first element in `lst` for which `fn` returns `True`.\n",
    "\n",
    "- 返回第一个满足条件的值\n",
    "- 返回最后一个满足条件的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:15:14.276740Z",
     "start_time": "2020-08-29T11:15:14.272739Z"
    }
   },
   "outputs": [],
   "source": [
    "def find(lst, fn):\n",
    "    return next(x for x in lst if fn(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:19:31.599585Z",
     "start_time": "2020-08-29T11:19:31.594778Z"
    }
   },
   "outputs": [],
   "source": [
    "def find_last(lst, fn):\n",
    "    return next(x for x in lst[::-1] if fn(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:19:33.342134Z",
     "start_time": "2020-08-29T11:19:33.334620Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "print(find([1, 2, 3, 4], lambda n: n % 2 == 0))\n",
    "print(find_last([1, 2, 3, 4], lambda n: n % 2 == 0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [spread](https://www.30secondsofcode.org/python/s/spread)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Flattens a list, by spreading its elements into a new list.\n",
    "\n",
    "Loop over elements, use `list.extend()` if the element is a list, `list.append()` otherwise.\n",
    "\n",
    "`extend()` 函数用于在列表末尾一次性追加另一个序列中的多个值（用新列表扩展原来的列表）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:10:40.912707Z",
     "start_time": "2020-08-29T11:10:40.907798Z"
    }
   },
   "outputs": [],
   "source": [
    "def spread(arg):\n",
    "    ret = []\n",
    "    for i in arg:\n",
    "        ret.extend(i) if isinstance(i, list) else ret.append(i)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:12:19.628745Z",
     "start_time": "2020-08-29T11:12:19.622046Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
     ]
    }
   ],
   "source": [
    "print(spread([1, 2, 3, [4, 5, 6], [7], 8, 9]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# part-2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## max_element_index\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the index of the element with the maximum value in a list.\n",
    "\n",
    "Use `max()` and `list.index()` to get the maximum value in the list and return its index."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:25:51.750045Z",
     "start_time": "2020-08-29T11:25:51.745433Z"
    }
   },
   "outputs": [],
   "source": [
    "def max_element_index(arr):\n",
    "    return arr.index(max(arr))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:26:04.297751Z",
     "start_time": "2020-08-29T11:26:04.293295Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n"
     ]
    }
   ],
   "source": [
    "print(max_element_index([5, 8, 9, 7, 10, 3, 0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## all_equal\n",
    "Python, List, Beginner\n",
    "\n",
    "Checks if all elements in a list are equal.\n",
    "\n",
    "Use `[1:]` and `[:-1]` to compare all the values in the given list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:26:54.616385Z",
     "start_time": "2020-08-29T11:26:54.611695Z"
    }
   },
   "outputs": [],
   "source": [
    "def all_equal(lst):\n",
    "    return lst[1:] == lst[:-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:27:16.769771Z",
     "start_time": "2020-08-29T11:27:16.763784Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(all_equal([1, 2, 3, 4, 5, 6]))\n",
    "print(all_equal([1, 1, 1, 1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [intersection](https://www.30secondsofcode.org/python/s/intersection) & union\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns a list of elements that exist in both lists.\n",
    "\n",
    "Create a `set` from `a` and `b`, then use the built-in set operator `&` to only keep values contained in both sets, then transform the `set` back into a `list`.\n",
    "\n",
    "`set()` 函数创建一个无序不重复元素集，可进行关系测试，删除重复数据，还可以计算交集(&)、差集(-)、并集(+)等。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:39:49.297871Z",
     "start_time": "2020-08-29T11:39:49.293044Z"
    }
   },
   "outputs": [],
   "source": [
    "def intersection(a, b):\n",
    "    _a, _b = set(a), set(b)\n",
    "    return list(_a & _b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:42:17.881151Z",
     "start_time": "2020-08-29T11:42:17.876607Z"
    }
   },
   "outputs": [],
   "source": [
    "def union(a, b):\n",
    "    return list(a + b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:42:19.641512Z",
     "start_time": "2020-08-29T11:42:19.636359Z"
    }
   },
   "outputs": [],
   "source": [
    "def union_diff(a, b):\n",
    "    return list(set(a + b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:42:28.823577Z",
     "start_time": "2020-08-29T11:42:28.816817Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3]\n",
      "[2, 2, 3, 4, 3, 2]\n",
      "[2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "print(intersection([2, 2, 3], [4, 3, 2]))\n",
    "print(union([2, 2, 3], [4, 3, 2]))\n",
    "print(union_diff([2, 2, 3], [4, 3, 2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [difference](https://www.30secondsofcode.org/python/s/difference)\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the difference between two iterables.\n",
    "\n",
    "Create a `set` from `b`, then use list comprehension on `a` to only keep values not contained in the previously created set, `_b`.\n",
    "\n",
    "集合a有，集合b没有的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:44:15.012781Z",
     "start_time": "2020-08-29T11:44:15.007454Z"
    }
   },
   "outputs": [],
   "source": [
    "def difference(a, b):\n",
    "    _b = set(b)\n",
    "    return [item for item in a if item not in _b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:44:30.026772Z",
     "start_time": "2020-08-29T11:44:30.022423Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 5]\n"
     ]
    }
   ],
   "source": [
    "print(difference([1, 2, 3, 5], [1, 2, 4]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## tail\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns all elements in a list except for the first one.\n",
    "\n",
    "Return `lst[1:]` if the list's length is more than `1`, otherwise, return the whole list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:45:37.484431Z",
     "start_time": "2020-08-29T11:45:37.479237Z"
    }
   },
   "outputs": [],
   "source": [
    "def tail(lst):\n",
    "    return lst[1:] if len(lst) > 1 else lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T11:46:08.836764Z",
     "start_time": "2020-08-29T11:46:08.831572Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3]\n",
      "[1]\n"
     ]
    }
   ],
   "source": [
    "print(tail([1, 2, 3]))\n",
    "print(tail([1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [max_n](https://www.30secondsofcode.org/python/s/max-n) & min_n\n",
    "Python, List, Math, Beginner\n",
    "\n",
    "Returns the `n` maximum elements from the provided list. If `n` is greater than or equal to the provided list's length, then return the original list (sorted in descending order).\n",
    "\n",
    "Use `sorted()` to sort the list, `[:n]` to get the specified number of elements. Omit the second argument, `n`, to get a one-element list.\n",
    "\n",
    "---\n",
    "`sorted()` 函数对所有可迭代的对象进行排序操作。\n",
    "\n",
    "**sort 与 sorted 区别：**\n",
    "- sort 是应用在 list 上的方法，sorted 可以对所有可迭代的对象进行排序操作。\n",
    "- list 的 sort 方法返回的是对已经存在的列表进行操作，而内建函数 sorted 方法返回的是一个新的 list，而不是在原来的基础上进行的操作。\n",
    "\n",
    "**语法**\n",
    "```py\n",
    "sorted(iterable, key=None, reverse=False)  \n",
    "```\n",
    "**参数说明：**\n",
    "\n",
    "- iterable -- 可迭代对象。\n",
    "- key -- 主要是用来进行比较的元素，只有一个参数，具体的函数的参数就是取自于可迭代对象中，指定可迭代对象中的一个元素来进行排序。\n",
    "- reverse -- 排序规则，reverse = True 降序 ， reverse = False 升序（默认）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T12:29:50.869267Z",
     "start_time": "2020-08-29T12:29:50.861931Z"
    }
   },
   "outputs": [],
   "source": [
    "def max_n(lst, n=1):\n",
    "    return sorted(lst, reverse=True)[:n]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T12:32:09.527759Z",
     "start_time": "2020-08-29T12:32:09.523744Z"
    }
   },
   "outputs": [],
   "source": [
    "def min_n(lst, n=1):\n",
    "    return sorted(lst, reverse=False)[:n]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T12:32:24.556994Z",
     "start_time": "2020-08-29T12:32:24.548545Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3]\n",
      "[3, 2]\n",
      "[1]\n",
      "[1, 2]\n"
     ]
    }
   ],
   "source": [
    "print(max_n([1, 2, 3]))\n",
    "print(max_n([1, 2, 3], 2))\n",
    "print(min_n([1, 2, 3]))\n",
    "print(min_n([1, 2, 3], 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [compact](https://www.30secondsofcode.org/python/s/compact)\n",
    "Python, List, Beginner\n",
    "\n",
    "Removes falsey values from a list.\n",
    "\n",
    "Use `filter()` to filter out falsey values (`False`, `None`, `0`, and `\"\"`).\n",
    "\n",
    "---\n",
    "`filter()` 函数用于过滤序列，过滤掉不符合条件的元素，返回由符合条件元素组成的新列表。\n",
    "\n",
    "该接收两个参数，第一个为函数，第二个为序列，序列的每个元素作为参数传递给函数进行判断，然后返回 True 或 False，最后将返回 True 的元素放到新列表中。\n",
    "\n",
    "**语法**\n",
    "```py\n",
    "filter(function, iterable)\n",
    "```\n",
    "**参数**\n",
    "- function -- 判断函数。\n",
    "- iterable -- 可迭代对象。\n",
    "\n",
    "**返回值**\n",
    "\n",
    "返回列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T13:50:10.782741Z",
     "start_time": "2020-08-29T13:50:10.778356Z"
    }
   },
   "outputs": [],
   "source": [
    "def compact(lst):\n",
    "    return list(filter(None, lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T13:50:22.494779Z",
     "start_time": "2020-08-29T13:50:22.489880Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 'a', 's', 34]\n"
     ]
    }
   ],
   "source": [
    "print(compact([0, 1, False, 2, '', 3, 'a', 's', 34]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T13:53:07.756773Z",
     "start_time": "2020-08-29T13:53:07.750103Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 0]\n"
     ]
    }
   ],
   "source": [
    "# test\n",
    "print(list(filter(lambda x:x%2 == 0 ,[2,3,0,1])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [includes_all](https://www.30secondsofcode.org/python/s/includes-all)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns `True` if all the elements in `values` are included in `lst`, `False` otherwise.\n",
    "\n",
    "Check if every value in `values` is contained in `lst` using a `for` loop, returning `False` if any one value is not found, `True` otherwise.\n",
    "\n",
    "\n",
    "def includes_all(lst, values):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T13:58:02.537147Z",
     "start_time": "2020-08-29T13:58:02.532136Z"
    }
   },
   "outputs": [],
   "source": [
    "def includes_all(lst, values):\n",
    "    for v in values:\n",
    "        if v not in lst:\n",
    "            return False\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T13:58:18.617787Z",
     "start_time": "2020-08-29T13:58:18.612019Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(includes_all([1, 2, 3, 4], [1, 4]))\n",
    "print(includes_all([1, 2, 3, 4], [1, 5]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [includes_any](https://www.30secondsofcode.org/python/s/includes-any)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns `True` if any element in `values` is included in `lst`, `False` otherwise.\n",
    "\n",
    "Check if any value in `values` is contained in `lst` using a `for` loop, returning `True` if any one value is found, `False` otherwise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:04:25.992772Z",
     "start_time": "2020-08-29T14:04:25.988861Z"
    }
   },
   "outputs": [],
   "source": [
    "def includes_any(lst, values):\n",
    "    for v in values:\n",
    "        if v in lst:\n",
    "            return True\n",
    "    return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:05:20.516215Z",
     "start_time": "2020-08-29T14:05:20.509302Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(includes_any([1, 2, 3, 4], [2, 9]))\n",
    "print(includes_any([1, 2, 3, 4], [8, 9]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [have_same_contents](https://www.30secondsofcode.org/python/s/have-same-contents)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns `True` if two lists contain the same elements regardless of order, `False` otherwise.\n",
    "\n",
    "Use `set()` on the combination of both lists to find the unique values. Iterate over them with a `for` loop comparing the `count()` of each unique value in each list. Return `False` if the counts do not match for any element, `True` otherwise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:02:33.158038Z",
     "start_time": "2020-08-29T14:02:33.152498Z"
    }
   },
   "outputs": [],
   "source": [
    "def have_same_contents(a, b):\n",
    "    for v in set(a + b):\n",
    "        if a.count(v) != b.count(v):\n",
    "            return False\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:02:43.914839Z",
     "start_time": "2020-08-29T14:02:43.908658Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(have_same_contents([1, 2, 4], [2, 4, 1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## unique_elements\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns the unique elements in a given list.\n",
    "\n",
    "Create a `set` from the list to discard duplicated values, then return a `list` from it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:06:31.365695Z",
     "start_time": "2020-08-29T14:06:31.360525Z"
    }
   },
   "outputs": [],
   "source": [
    "def unique_elements(li):\n",
    "    return list(set(li))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:06:41.814619Z",
     "start_time": "2020-08-29T14:06:41.808452Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "print(unique_elements([1, 2, 2, 3, 4, 3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [count_occurences](https://www.30secondsofcode.org/python/s/count-occurences)\n",
    "Python, List, Beginner\n",
    "\n",
    "Counts the occurrences of a value in a list.\n",
    "\n",
    "Increment a counter for every item in the list that has the given value and is of the same type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:07:47.031741Z",
     "start_time": "2020-08-29T14:07:47.028413Z"
    }
   },
   "outputs": [],
   "source": [
    "def count_occurrences(lst, val):\n",
    "    return len([x for x in lst if x == val and type(x) == type(val)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:07:54.993760Z",
     "start_time": "2020-08-29T14:07:54.987768Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "print(count_occurrences([1, 1, 2, 1, 2, 3], 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## [is_contained_in](https://www.30secondsofcode.org/python/s/is-contained-in)\n",
    "Python, List, Intermediate\n",
    "\n",
    "Returns `True` if the elements of the first list are contained in the second one regardless of order, `False` otherwise.\n",
    "\n",
    "Use `count()` to check if any value in `a` has more occurences than it has in `b`, returning `False` if any such value is found, `True` otherwise.\n",
    "\n",
    "集合b包含集合a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:12:41.013525Z",
     "start_time": "2020-08-29T14:12:41.008151Z"
    }
   },
   "outputs": [],
   "source": [
    "def is_contained_in(a, b):\n",
    "    for v in set(a):\n",
    "        if a.count(v) > b.count(v):\n",
    "            return False\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:12:49.114396Z",
     "start_time": "2020-08-29T14:12:49.108035Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(is_contained_in([1, 4], [2, 4, 1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## has_duplicates & all_unique\n",
    "Python, List, Beginner\n",
    "\n",
    "Returns `True` if there are duplicate values in a flat list, `False` otherwise.\n",
    "\n",
    "Use `set()` on the given list to remove duplicates, compare its length with the length of the list.\n",
    "\n",
    "- 是否存在重复元素\n",
    "- 元素是否唯一"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-10-11T11:39:00.756843Z",
     "start_time": "2020-10-11T11:39:00.752970Z"
    }
   },
   "outputs": [],
   "source": [
    "def has_duplicates(lst):\n",
    "    return len(lst) != len(set(lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:16:48.939774Z",
     "start_time": "2020-08-29T14:16:48.935385Z"
    }
   },
   "outputs": [],
   "source": [
    "def all_unique(lst):\n",
    "    return len(lst) == len(set(lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:14:27.653733Z",
     "start_time": "2020-08-29T14:14:27.647368Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "x = [1, 2, 3, 4, 5, 5]\n",
    "y = [1, 2, 3, 4, 5]\n",
    "print(has_duplicates(x))\n",
    "print(has_duplicates(y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-08-29T14:16:49.125855Z",
     "start_time": "2020-08-29T14:16:49.118479Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "x = [1, 2, 3, 4, 5, 6]\n",
    "y = [1, 2, 2, 3, 4, 5]\n",
    "print(all_unique(x))\n",
    "print(all_unique(y))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
